from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.generics import ListAPIView, GenericAPIView, CreateAPIView
from rest_framework.filters import OrderingFilter
from rest_framework.permissions import IsAuthenticated

from mlh.utils.pagination import StandardResultsSetPagination
from users.models import User
from .serializers import QuestionSerializer, AnswerSerializer, QuestionIndexSerializer, TagsSerializer, LikeSerializer, \
    AnswerCommitSerializer, QuestionSubmitSerializer
from .models import Question, Answer, Tags, QuestionTag


class QuestionDetailView(APIView):
    """
    问答详情
    请求方式：GET
    url: /questions/{pk}/
    :return: json
    """

    # permission_classes = [IsAuthenticated]  # 指明必须登录认证后才能访问

    def perform_authentication(self, request):
        """关闭认证机制"""
        pass

    def get(self, request, pk):
        """返回问题详情和回答详情"""
        try:
            question = Question.objects.get(id=pk)
        except Exception:
            return Response({"message": "该问题不存在"}, status=status.HTTP_400_BAD_REQUEST)

        question.hits += 1
        question.save()

        answer = Answer.objects.filter(question_id=pk).order_by("-create_time")

        # 序列化
        question_serializer = QuestionSerializer(question)
        answer_serializer = AnswerSerializer(answer, many=True)

        data = {
            "question": question_serializer.data,
            "answer": answer_serializer.data
        }

        return Response(data)

    def put(self, request, pk):
        """问题的点赞数以及评论的点赞数"""
        # 传入数据格式 {"qs_like": 1}

        # 用户不登录就不能点赞
        user = request.user
        if not user:
            return Response({'message': "当前用户未登录"}, status=status.HTTP_401_UNAUTHORIZED)

        # 当前用户不能给自己点赞
        ques_id = request.query_params.get('question_id')
        try:
            ques_id = int(ques_id)
        except ValueError:
            return Response({'message': "参数错误"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            user_id = Question.objects.get(id=ques_id).user.id
        except Exception:
            return Response({'message': "其他错误"}, status=status.HTTP_400_BAD_REQUEST)

        if user.id == user_id:
            return Response({'message': "用户不能给自己点赞"}, status=status.HTTP_400_BAD_REQUEST)

        serializer = LikeSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        qs_like = serializer.validated_data['qs_like']

        try:
            qs_obj = Question.objects.get(id=pk)
        except Exception:
            return Response({"message": "该问题不存在"}, status=status.HTTP_400_BAD_REQUEST)

        qs_obj.likes_count += qs_like
        if qs_obj.likes_count < 0:
            return Response({"message": "点赞数不能为负"})
        qs_obj.save()

        return Response({"message": "OK"})

    def post(self, request, pk):
        """当前问题回答的提交存储"""
        # 请求方式 post 请求地址  questions/(?P<pk>\d+)/
        # 传入格式 {“content”:"xxxxx"}
        # 可以通过当前问题的id去查找到当前的模型类，user_id去查找当前的用户模型类，用create方法去保存

        commitserializer = AnswerCommitSerializer(data=request.data, context={"question": pk, "request": request})
        commitserializer.is_valid(raise_exception=True)
        commitserializer.save()

        question = Question.objects.get(id=pk)
        question.answer_count += 1
        question.save()

        return Response(status=status.HTTP_201_CREATED)


class AnswerLikesView(GenericAPIView):
    """
    回答点赞
    """
    serializer_class = LikeSerializer
    permission_classes = [IsAuthenticated]  # 指明必须登录认证后才能访问

    def put(self, request, *args, **kwargs):

        # 用户不登录就不能点赞
        user = request.user
        if not user:
            return Response({'message': "当前用户未登录"}, status=status.HTTP_401_UNAUTHORIZED)

        # 当前用户不能给自己点赞
        ans_id = request.query_params.get('answer_id')
        try:
            ans_id = int(ans_id)
        except ValueError:
            return Response({'message': "参数错误"}, status=status.HTTP_400_BAD_REQUEST)

        try:
            user_id = Answer.objects.get(id=ans_id).user.id
        except Exception:
            return Response({'message': "其他错误"}, status=status.HTTP_400_BAD_REQUEST)

        if user.id == user_id:
            return Response({'message': "用户不能给自己点赞"}, status=status.HTTP_400_BAD_REQUEST)

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        answer_id = serializer.validated_data['answer_id']
        qs_like = serializer.validated_data['qs_like']

        # 获取当前的回答
        try:
            an_obj = Answer.objects.get(id=answer_id)
        except Exception:
            return Response({"message": "该回答不存在"}, status=status.HTTP_400_BAD_REQUEST)

        an_obj.likes_count += qs_like
        if an_obj.likes_count < 0:
            return Response({"message": "点赞数不能为负"})
        an_obj.save()

        return Response({"message": "OK"})


class QuestionIndexView(ListAPIView):
    """
    问答首页
    请求方式：GET
    参数：page（页数）、page_size（每页数量）、ordering（create_time、answer_count 排序关键字）
    url: /questions/?page&page_size&ordering
    :return json
    """
    # [
    #     {
    #         "id": 1,  # 问题的id，跳转用
    #         "question_username": "李四",
    #         "answer_username": "张三",
    #         "tags": ["java", "python"],
    #         "hints": "50",  # 阅读量
    #         "create_time": "2018-12-12 xxx",  # 创建时间
    #         "title": "怎么处理这个问题",
    #         "like": 10,
    #         "answer_count": 20
    #     },
    #     ....
    # ]
    queryset = Question.objects.all().order_by('-create_time')
    serializer_class = QuestionIndexSerializer
    pagination_class = StandardResultsSetPagination
    # 排序
    filter_backends = (DjangoFilterBackend,)
    ordering_fields = ('create_time', 'likes_count')
    filter_fields = ('answer_count',)


class TagsView(ListAPIView):
    """
    所有标签
    请求方式：GET
    url: /questions/tags/
    :return json
    """
    # [
    #     {
    #         "id": 1,  # 标签id
    #         "name": "java",  # 标签名
    #         "tags_count": 12,  # 关注数量
    #         "status": False,  # 是否关注该标签
    #     },
    #     ...
    # ]
    queryset = Tags.objects.all()
    serializer_class = TagsSerializer
    # 排序
    filter_backends = (OrderingFilter,)
    ordering_fields = ('tags_count',)


class QuestionSubmitView(CreateAPIView):
    """
    用户问题的提交
    请求方式 POST  url： questions/submission/
    前端返回的内容
    {
        "title": "xxxx",
        "tags": "python,java,xxx",
        "content": "xxxxxxxxxx"
    }
    后端返回给前端的内容
    创建后问题的id
    status=201
    """

    queryset = Question
    serializer_class = QuestionSubmitSerializer
    permission_classes = [IsAuthenticated]

    def create(self, request, *args, **kwargs):
        resp = super().create(request, *args, **kwargs)
        # 获取创建好的问题id以及标签
        tags = request.data.get('tags')
        if not isinstance(tags, str):
            return Response({'message': "无效的标签"}, status=status.HTTP_400_BAD_REQUEST)
        question_id = resp.data.get('id')

        # 对tags进行切分
        tags = tags.split(",")
        question = Question.objects.get(id=question_id)

        # 获取当前的模型类
        for tag in tags:
            try:
                _tag = Tags.objects.get(name=tag)
            except Exception:
                pass
            else:
                # 保存数据
                QuestionTag.objects.create(question=question, tags=_tag)

        return resp
